package com.tbit.main.service.impl;

import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tbit.main.constant.*;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;

/**
 * @author LMY
 * @create 2022-07-19 17:35
 * 网关设备推送
 */
@Slf4j
@Service("machinePushListenter")
public class MachinePushListener {
    @Autowired
    private CameraService cameraService;
    @Autowired
    private DataService dataService;
    @Autowired
    private MachineAbnormalService machineAbnormalService;
    @Autowired
    private HelmetService helmetService;
    @Autowired
    private HelmetAbnormalService helmetAbnormalService;
    @Autowired
    private HelmetBoundService helmetBoundService;
    @Autowired
    private MannedEventService mannedEventService;

    @RabbitListener(queues = {"${mq.queue.tbitUqbikeTerEvent}"}, concurrency = "5")
    @RabbitHandler
    public void onMessage(Message msg) {
        try {
            String respMsg = new String(msg.getBody(), StandardCharsets.UTF_8);
            //判断消息类型
            JSONObject object = JSON.parseObject(respMsg);
            log.info("中控设备消息推送内容::" + object);

            String dataContent = object.getString("data");
            if (StringUtils.isBlank(dataContent)) {
                log.info("中控设备事件推送:无数据内容");
                return;
            }

            int msgId = object.getIntValue("msgId");
            switch (msgId) {
                case GatewayProtocol.MQ_MSG_ID_EVENT_LOGIN_PUSH:
                    /*发送结果回复*/
                    TerInfo terInfo = JSONObject.parseObject(dataContent, TerInfo.class);
                    if (dataService.getId(terInfo.getMachineNO()) != null) {
                        Integer accountId = dataService.getAccountId(terInfo.getMachineNO());
                        Camera camera = new Camera(accountId, terInfo.getMachineNO(), terInfo.getSoftVersion());
                        cameraService.update(camera);
                    }
                    break;

                case GatewayProtocol.MQ_MSG_ID_EVENT_PUSH:
                    //事件推送
                    TerInfoUpload terInfoUpload = JSON.parseObject(dataContent, TerInfoUpload.class);
                    String machineNo = terInfoUpload.getMno();
                    Integer machineId = dataService.getId(machineNo);
                    if (Objects.isNull(machineId)) {
                        log.info("中控设备事件推送:设备已删除");
                        return;
                    }

                    //头盔锁故障恢复事件
                    if (ArrayUtil.contains(EventType.getHelmet(), terInfoUpload.getEventType())) {
                        helmetLockFailureRecoveryEvent(machineId, terInfoUpload.getEventType());
                    }

                    //太阳能板充电异常
                    if (ArrayUtil.contains(EventType.SOLAR, terInfoUpload.getEventType())) {
                        solarEvent(machineId, terInfoUpload.getEventType());
                    }

                    //设备载人事件
                    if (ArrayUtil.contains(EventType.getManned(), terInfoUpload.getEventType())) {
                        Integer accountId = dataService.getAccountId(machineNo);
                        AccountConfigExt accountConfigExt = dataService.getAccountidExt(accountId + AccountConfigExtConstant.mannedAbnormal);
                        if (accountConfigExt != null && Integer.valueOf(accountConfigExt.getParamValue()).equals(1)) {
                            mannedEventService.mannedEvent(machineId, terInfoUpload.getEventType());
                        }
                    }


                    break;
                default:
                    log.warn("未知消息类型=" + msgId);
            }

        } catch (Exception e) {
            log.error("网关设备推送异常", e);
        }
    }

    private void solarEvent(Integer machineId, Integer eventType) {
        MachineAbnormal abnormal = machineAbnormalService.getByMachineIdAndType(machineId, MachineAbnormalConstant.SOLAR_UNCHARGED);
        if (Objects.equals(eventType, EventType.SOLAR_UNCHARGED_EVENT)) {
            //异常上报
            if (Objects.isNull(abnormal)) {
                machineAbnormalService.insert(new MachineAbnormal(machineId, MachineAbnormalConstant.SOLAR_UNCHARGED));
            } else {
                machineAbnormalService.del(machineId, MachineAbnormalConstant.SOLAR_UNCHARGED);
                machineAbnormalService.insert(new MachineAbnormal(machineId, MachineAbnormalConstant.SOLAR_UNCHARGED));
            }
        } else if (Objects.equals(eventType, EventType.SOLAR_CHARGED_EVENT)) {
            //检测到充电事件  恢复异常
            machineAbnormalService.del(machineId, MachineAbnormalConstant.SOLAR_UNCHARGED);
        }
    }

    private void helmetLockFailureRecoveryEvent(Integer machineId, Integer eventType) {
        if (Objects.equals(eventType, EventType.HELMET_LINK)) {
            helmetAbnormalService.del(machineId, HelmetStatus.HELMET_LINK);
        } else if (Objects.equals(eventType, EventType.HELMET_SOC)) {
            helmetAbnormalService.del(machineId, HelmetStatus.HELMET_SOC);
        } else if (Objects.equals(eventType, EventType.HELMET_IO)) {
            helmetAbnormalService.del(machineId, HelmetStatus.HELMET_IO);
        }

        machineAbnormalService.del(machineId, MachineAbnormalConstant.MACHINE_ABNORMAL__HELMET);
        Helmet helmet = helmetBoundService.getMachineId(machineId);
        if (helmet != null) {
            List<HelmetAbnormal> helmetAbnormalList = helmetAbnormalService.getMachineId(machineId);
            if (CollectionUtils.isEmpty(helmetAbnormalList)) {
                helmetService.updateState(helmet.getHelmetMac(), 0);
            }
        }
    }

}
